﻿/**
 * @file hash_ie1.cpp
 * Copyright (c) 2022 Gaaagaa. All rights reserved.
 * 
 * @author  : Gaaagaa
 * @date    : 2022-06-20
 * @version : 1.0.0.0
 * @brief   : 对 哈希表结构 容器的数据进行 插入/删除 操作对比测试。
 */

/**
 * The MIT License (MIT)
 * Copyright (c) Gaaagaa. All rights reserved.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is furnished to do
 * so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "std_hash.h"
#include "std_mdebug.h"
#include <stdio.h>

#include <unordered_set>

////////////////////////////////////////////////////////////////////////////////

/**********************************************************/
/**
 * @brief 打印输出 xstd_hash_t 对象的各个节点元素。
 */
xstd_void_t printf_hash_int32(xhash_this_t xhash_this)
{
    xstd_size_t  xst_count  = 0;
    xhash_iter_t xhash_iter = std_hash_begin(xhash_this);
    xhash_iter_t xhash_vend = std_hash_end(xhash_this);

    if (std_hash_size(xhash_this) <= 0)
    {
        printf("hash(0) \n");
        return;
    }

    printf("hash(%d) [[[\n", (xstd_int32_t)std_hash_size(xhash_this));

    for (xst_count  = 0;
         xhash_iter != xhash_vend;
         xhash_iter  = std_hash_next(xhash_iter))
    {
        printf("[%3d]=(%3d)",
            (xstd_int32_t)xst_count, std_hash_elem_int32(xhash_iter));

        if (++xst_count < std_hash_size(xhash_this))
        {
            if (0 == (xst_count & 7))
                printf("\n");
            else
                printf(" , ");
        }
        else
        {
            printf("\n]]] hash\n\n");
        }
    }
}

/**********************************************************/
/**
 * @brief 打印输出 std::hash_set 对象的各个节点元素。
 */
xstd_void_t printf_hash_set_int32(const std::unordered_set< xstd_int32_t > & xhash_set)
{
    xstd_size_t  xst_count  = 0;
    std::unordered_set< xstd_int32_t >::const_iterator xhash_iter = xhash_set.begin();
    std::unordered_set< xstd_int32_t >::const_iterator xhash_vend = xhash_set.end();

    if (xhash_set.size() <= 0)
    {
        printf("hash_set(0) \n");
        return;
    }

    printf("hash_set(%d) [[[\n", (xstd_int32_t)xhash_set.size());

    for (xst_count = 0; xhash_iter != xhash_vend; ++xhash_iter)
    {
        printf("[%3d]=(%3d)",
            (xstd_int32_t)xst_count, *xhash_iter);

        if (++xst_count < xhash_set.size())
        {
            if (0 == (xst_count & 7))
                printf("\n");
            else
                printf(" , ");
        }
        else
        {
            printf("\n]]] hash_set\n\n");
        }
    }
}

////////////////////////////////////////////////////////////////////////////////

int main(int argc, char * argv[])
{
    xmdb_this_t  xmdb_comm  = XSTD_NULL;
    xstd_int32_t   xit_iter   = 0;
    xhash_this_t xhash_this = XSTD_NULL;

    std::unordered_set< xstd_int32_t > xhash_set;

    //======================================

    xmdb_comm = (xmdb_this_t)std_mdbcomm_start();

    printf("%d. mem count : %d\n", __LINE__, (xstd_int32_t)std_mdbcomm_count());

    xhash_this = std_hash_create_int32();

    printf("%d. load factor : [ %f <=> %f ]\n", __LINE__, std_hash_load_factor(xhash_this), xhash_set.load_factor());
    printf("%d. mem count   : %d, sizeof(xstd_hash_t) = %d\n",
           __LINE__,
           (xstd_int32_t)std_mdbcomm_count(),
           (xstd_int32_t)std_hash_sizeof());

    printf("\n\n======================================\n");

    //======================================
    // insert

    printf("INSERT PRINT: \n");

    for (xit_iter = 1; xit_iter <= 100; ++xit_iter)
    {
        std_hash_insert_int32(xhash_this, xit_iter);
    }

    printf_hash_int32(xhash_this);

    for (xit_iter = 1; xit_iter <= 100; ++xit_iter)
    {
        xhash_set.insert(xit_iter);
    }

    printf_hash_set_int32(xhash_set);

    printf("%d. load factor : [ %f <=> %f ]\n", __LINE__, std_hash_load_factor(xhash_this), xhash_set.load_factor());
    printf("%d. mem count   : %d\n", __LINE__, (xstd_int32_t)std_mdbcomm_count());

    printf("\n\n======================================\n");

    //======================================
    // erase

    printf("ERASE PRINT: \n");

    for (xit_iter = 1; xit_iter <= 37; ++xit_iter)
    {
        std_hash_erase_int32(xhash_this, 2 * xit_iter);
    }

    printf_hash_int32(xhash_this);

    for (xit_iter = 1; xit_iter <= 37; ++xit_iter)
    {
        xhash_set.erase(2 * xit_iter);
    }

    printf_hash_set_int32(xhash_set);

    printf("%d. load factor : [ %f <=> %f ]\n", __LINE__, std_hash_load_factor(xhash_this), xhash_set.load_factor());
    printf("%d. mem count   : %d\n", __LINE__, (xstd_int32_t)std_mdbcomm_count());
    printf("\n\n======================================\n");

    //======================================
    // clear

    printf("CLEAR: \n");

    std_hash_clear(xhash_this);
    printf_hash_int32(xhash_this);

    xhash_set.clear();

    printf("%d. load factor : [ %f <=> %f ]\n", __LINE__, std_hash_load_factor(xhash_this), xhash_set.load_factor());
    printf("%d. mem count   : %d\n", __LINE__, (xstd_int32_t)std_mdbcomm_count());
    printf("\n\n======================================\n");

    //======================================

    std_hash_destroy(xhash_this);

    printf("%d. mem count : %d\n", __LINE__, (xstd_int32_t)std_mdbcomm_count());

    std_mdbcomm_stop();

    //======================================

    return 0;
}

